package cn.scau.server.service.impl;

import cn.scau.server.mapper.EmpMapper;
import cn.scau.server.mapper.EmpPosMapper;
import cn.scau.server.mapper.PositionMapper;
import cn.scau.server.pojo.Dept;
import cn.scau.server.mapper.DeptMapper;
import cn.scau.server.pojo.Emp;
import cn.scau.server.pojo.EmpPos;
import cn.scau.server.pojo.Position;
import cn.scau.server.service.Component;
import cn.scau.server.service.DeptService;
import cn.scau.server.utils.MobileUserHolder;
import cn.scau.server.vo.EmpPosDeptVO;
import cn.scau.server.vo.ResultVO;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author 代码不跑我先跑
 * @since 2025-03-30
 */
@Service
public class DeptServiceImpl extends ServiceImpl<DeptMapper, Dept> implements DeptService {
    @Autowired
    private DeptMapper deptMapper;

    @Autowired
    private EmpMapper empMapper;

    @Autowired
    private EmpPosMapper empPosMapper;

    @Autowired
    private PositionMapper positionMapper;

    // 构建部门和员工的树状结构
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Component buildTree() {
        List<Dept> deptList = deptMapper.selectList(null); // 获取所有部门

        Map<Integer, Dept> deptMap = new HashMap<>();
        for (Dept dept : deptList) {
            deptMap.put(dept.getId(), dept);
        }

        // 构建树状结构
        Dept root = new Dept(0, "Root", null); // 创建根节点
        for (Dept dept : deptList) {
            if (dept.getParentId() == 0) {
                root.add(dept);
            } else {
                Dept parent = deptMap.get(dept.getParentId());
                if (parent != null) {
                    parent.add(dept);
                }
            }
        }
        return root;
    }

    // 新增部门
    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResultVO addDept(String name, String parentName) {
        if (name == null || name.length() == 0) {
            return ResultVO.fail("部门名称不能为空");
        }

        // 根据部门名称查找上级部门
        QueryWrapper<Dept> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("name", parentName);
        Dept parentDept = deptMapper.selectOne(queryWrapper);
        if (parentDept == null) {
            return ResultVO.fail("上级部门不存在");
        }

        // 检查是否已经存在同名的部门
        QueryWrapper<Dept> querySameWrapper = new QueryWrapper<>();
        querySameWrapper.eq("name", name);
        Dept existingDept = deptMapper.selectOne(querySameWrapper);
        if (existingDept != null) {
            return ResultVO.fail("该部门已存在");
        }

        // 创建新部门
        Dept dept = new Dept();
        dept.setName(name);
        dept.setParentId(parentDept.getId());
        boolean success = deptMapper.insert(dept) > 0;
        if (success) {
            // 重新构建树状结构
            buildTree();
            return ResultVO.success("新增部门成功");
        } else {
            return ResultVO.fail("新增部门失败");
        }
    }

    // 删除部门及其所有子部门
    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResultVO  deleteDeptByName(String name) {
        // 根据部门名称查找部门
        QueryWrapper<Dept> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("name", name);
        Dept dept = deptMapper.selectOne(queryWrapper);
        if (dept == null) {
            return ResultVO.fail("部门不存在");
        }

        // 检查部门下是否有员工或员工后代
        if (hasEmpInDeptOrSubDepts(dept.getId())) {
            return ResultVO.fail("删除失败，该部门下还有员工");
        }

        // 删除部门及其所有子部门
        List<Integer> deptIdsToDelete = collectAllSubDepts(dept.getId());
        deptMapper.deleteBatchIds(deptIdsToDelete);

        // 重新构建树状结构
        buildTree();
        return ResultVO.success("删除部门成功");
    }

    // 检查部门下是否有员工
    private boolean hasEmpInDeptOrSubDepts(Integer deptId) {
        QueryWrapper<EmpPos> empPosQueryWrapper = new QueryWrapper<>();
        empPosQueryWrapper.eq("dept_id", deptId);
        List<EmpPos> subEmpPos = empPosMapper.selectList(empPosQueryWrapper);

        // 提取员工编号
        List<String> empIds = subEmpPos.stream()
                .map(EmpPos::getEmpId)
                .toList();

        // 如果没有员工编号，直接返回 false
        if (empIds.isEmpty()) {
            return false;
        }

        // 查询这些员工编号对应的员工是否被逻辑删除
        QueryWrapper<Emp> empQueryWrapper = new QueryWrapper<>();
        empQueryWrapper.in("emp_id", empIds)
                .eq("is_deleted", 0);
        List<Emp> activeEmps = empMapper.selectList(empQueryWrapper);

        // 如果存在未被逻辑删除的员工，则返回 true
        if (!activeEmps.isEmpty()) {
            return true;
        }

        // 递归检查所有子部门
        QueryWrapper<Dept> deptQueryWrapper = new QueryWrapper<>();
        deptQueryWrapper.eq("parent_id", deptId);
        List<Dept> subDepts = deptMapper.selectList(deptQueryWrapper);
        for (Dept subDept : subDepts) {
            if (hasEmpInDeptOrSubDepts(subDept.getId())) {
                return true; // 如果子部门下有员工，则返回true
            }
        }
        return false; // 如果没有员工，则返回false
    }

    // 递归收集所有子部门
    private List<Integer> collectAllSubDepts(Integer deptId) {
        Set<Integer> deptIdsToDelete = new HashSet<>();
        deptIdsToDelete.add(deptId);// 首先将当前部门的 ID 加入列表
        QueryWrapper<Dept> deptQueryWrapper = new QueryWrapper<>();
        deptQueryWrapper.eq("parent_id", deptId);
        List<Dept> subDepts = deptMapper.selectList(deptQueryWrapper);
        for (Dept subDept : subDepts) {
            deptIdsToDelete.add(subDept.getId());
            deptIdsToDelete.addAll(collectAllSubDepts(subDept.getId())); // 递归收集所有子部门
        }
        return new ArrayList<>(deptIdsToDelete); // 将 Set 转换为 List 返回
    }

    // 根据当前员工ID获取所属部门及其所有子部门的ID列表
    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResultVO<List<Dept>> collectAllSubDeptsByEmpId() {
        System.out.println("根据当前员工ID获取所属部门及其所有子部门的ID列表");
        String empId= MobileUserHolder.getEmpPermission().getEmpId();

        QueryWrapper<EmpPos> qw1 = new QueryWrapper<>();
        qw1.eq("emp_id", empId)
                .select("dept_id"); // 只查询dept_id字段

        EmpPos empPos = empPosMapper.selectOne(qw1);
        if (empPos == null) {
            ResultVO.fail("此员工不属于任何部门");
        }
        List<Integer> deptIds = collectAllSubDepts(empPos.getDeptId());

        QueryWrapper<Dept> qw2 = new QueryWrapper<>();
        qw2.in("id", deptIds)
                .orderByAsc("id");
        List<Dept> result = deptMapper.selectList(qw2);

        System.out.println("共获得数据：" + result.size());
        System.out.println(result);
        return ResultVO.success("获取成功", result);
    }

    // 查找当前部门下的所有员工信息
    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResultVO<List<EmpPosDeptVO>> getEmpsUnderDept(String deptName) {
        // 根据部门名称查找部门
        QueryWrapper<Dept> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("name", deptName);
        Dept dept = deptMapper.selectOne(queryWrapper);
        if (dept == null) {
            return ResultVO.fail("部门不存在");
        }

        // 查询当前部门下的所有员工
        QueryWrapper<EmpPos> empPosQueryWrapper = new QueryWrapper<>();
        empPosQueryWrapper.eq("dept_id", dept.getId());
        List<EmpPos> empPosList = empPosMapper.selectList(empPosQueryWrapper);

        // 查询员工信息并封装到 EmpPosDeptVO
        List<EmpPosDeptVO> empPosDeptVOList = new ArrayList<>();
        for (EmpPos empPos : empPosList) {
            // 查询员工信息
            QueryWrapper<Emp> empQueryWrapper = new QueryWrapper<>();
            empQueryWrapper.eq("emp_id", empPos.getEmpId());
            empQueryWrapper.eq("is_deleted", 0);
            Emp emp = empMapper.selectOne(empQueryWrapper);

            // 如果员工不存在或已被逻辑删除，则跳过
            if (emp == null) {
                continue;
            }

            // 查询职位信息
            QueryWrapper<Position> positionQueryWrapper = new QueryWrapper<>();
            positionQueryWrapper.eq("id", empPos.getPositionId());
            Position position = positionMapper.selectOne(positionQueryWrapper);

            if (emp != null) {
                // 创建 EmpPosDeptVO 对象并添加到列表
                EmpPosDeptVO empPosDeptVO = new EmpPosDeptVO();
                empPosDeptVO.setEmpId(empPos.getEmpId());
                empPosDeptVO.setName(emp.getName());
                empPosDeptVO.setDeptId(dept.getId());
                empPosDeptVO.setDeptName(dept.getName());
                empPosDeptVO.setPositionId(empPos.getPositionId());
                empPosDeptVO.setPositionName(position != null ? position.getName() : "未知职位");
                empPosDeptVO.setIsLeader(empPos.getIsLeader());
                empPosDeptVO.setAge(emp.getAge());
                empPosDeptVOList.add(empPosDeptVO);
            }
        }
        return ResultVO.success("查询成功",empPosDeptVOList);
    }

    //根据部门ID获取部门名称
    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResultVO<String> getDeptNameById(Integer deptId) {
        try {
            if (deptId == null) {
                return ResultVO.fail("部门ID不能为空");
            }

            Dept dept = getById(deptId);
            if (dept == null) {
                return ResultVO.fail("找不到对应的部门");
            }

            return ResultVO.success("查询成功", dept.getName());
        } catch (Exception e) {
            return ResultVO.fail("查询部门名称异常: " + e.getMessage());
        }
    }

    //根据传入的部门号，找到该部门的父组织
    @Override
    public Integer findParent(Integer deptId) {
        if (deptId == null) {
            return null; // 如果传入的部门ID为空，直接返回null
        }

        // 查询指定部门的父部门ID
        QueryWrapper<Dept> queryWrapper = new QueryWrapper<>();
        queryWrapper.select("parent_id") // 只查询 parentId 字段，提高查询效率
                .eq("id", deptId);   // 根据部门ID查询

        Dept dept = deptMapper.selectOne(queryWrapper); // 执行查询
        if (dept != null) {
            return dept.getParentId(); // 返回父部门ID
        } else {
            return null; // 如果没有找到该部门，返回null
        }
    }

    // 计算树的层高
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int getDeptTreeHeight() {
        Dept root = (Dept)buildTree(); // 构建树状结构
        return calculateTreeHeight(root) - 1; // 从根节点开始计算层高，多建了一个不存在的根节点部门所以-1
    }

    // 递归计算树的层高
    private int calculateTreeHeight(Dept node) {
        if (node == null || node.getChildren() == null || node.getChildren().isEmpty()) {
            return 1; // 如果是叶子节点，层高为1
        }
        int maxSubHeight = 0;
        for (Component child : node.getChildren()) {
            int subHeight = calculateTreeHeight((Dept) child); // 递归计算子树的层高
            if (subHeight > maxSubHeight) {
                maxSubHeight = subHeight;
            }
        }
        return maxSubHeight + 1; // 当前节点的层高是子树最大层高加1
    }
}

